import os.path
import yaml
import json_tools
import logging

"""
json 比较工具
将读取的字符串类型转化为字典或列表，loader可以选择以下几种：
- BaseLoader：仅加载最基本的YAML
- SafeLoader：安全地加载YAML语言的子集。建议用于加载不受信任的输入。（safe_load）
- FullLoader：加载完整的YAML语言。避免任意代码执行。这是当前（PyYAML 5.1）默认加载器调用yaml.load(input)（发出警告后）（full_load）
- UnsafeLoader（也称为Loader向后兼容性）：原始的Loader代码，可以通过不受信任的数据输入轻松利用。
"""

def diffYml(srcYaml:str,targetYaml:str):
    """
    :param srcYaml: 源yaml文件
    :param targetYaml: 目标文件
    :return: 以字典形式返回结果，不同的类型和结果
    """
    result = {}
    prefix = 'files/'
    source = 'aaa'
    target = 'bbb'
    f_name_list = os.listdir(prefix + source)
    t_files = os.listdir(prefix + target)
    ignore_files = []
    # ignore_files = ['CAE-AUTHORIZATION.yaml']

    no_yml_file = list()
    s_diff_files = set(f_name_list) - set(t_files)
    if s_diff_files:
        print(target, '不存在的文件', s_diff_files)
    same_files = set(f_name_list) & set(t_files)
    if same_files:
        print(target, '共存的文件', same_files)

    print('\n-----------------------\n')

    s_stream = open(prefix + source + '/' + srcYaml, mode='r', encoding='utf-8')
    t_stream = open(prefix + target + '/' + targetYaml, mode='r', encoding='utf-8')
    s_data = yaml.load(s_stream, Loader=yaml.FullLoader)
    t_data = yaml.load(t_stream, Loader=yaml.FullLoader)
    s_stream.close()
    t_stream.close()
    if s_data == t_data:
        # print(f_name, '内容一致')
        pass
    else:
        logging.info('{}内容不一致'.format('a.yaml'))
        s_miss_dict, t_miss_dict = {}, {}
        s_diffKey, t_diffKey = {}, {}
        for diff in json_tools.diff(s_data, t_data):
            t_missKey = dict(diff).get('remove')
            s_missKey = dict(diff).get('add')
            diffKey = dict(diff).get('replace')
            value = dict(diff).get('value')
            prev = dict(diff).get('prev')
            # print(diff)
            if t_missKey:
                t_miss_dict[t_missKey] = prev
            if s_missKey:
                s_miss_dict[s_missKey] = value
            if diffKey:
                s_diffKey[diffKey] = prev
                t_diffKey[diffKey] = value

        if t_miss_dict:
            logging.info('\n{} 缺失'.format(target))
            list_targ_miss = []
            for k, v in t_miss_dict.items():
                val = "%s%s%s" %(k , '=' , v)
                list_targ_miss.append(val)
                logging.info('   ', k, '=', v)
            result['target_miss_value'] = list_targ_miss
        if s_miss_dict:
            logging.info('\n', source, '缺失')
            list_miss = []
            for k, v in s_miss_dict.items():
                al = "%s%s%s" %(k , '=' , v)
                list_miss.append(val)
                logging.info('   ', k, '=', v)
            result['src_miss_value'] = list_miss
        if s_diffKey:
            logging.info('\n属性值不同')
            list_attr = []
            for k, v in s_diffKey.items():
                val = '\n    「{} -> {}」：{} -> {}'.format(source, target, abbr_txt(v), abbr_txt(t_diffKey.get(k)))
                list_attr.append(val)
            result['attr_diff'] = list_attr
    return result

def abbr_txt(data):
    if isinstance(data, str) and len(data) > 90:
        return data[:90] + '...';
    else:
        return data


if __name__ == '__main__':
    result = diffYml('a.yaml','b.yaml')
    print(result)

